﻿using FileSystem.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FileSystem.impl.Actions
{
    class ExecuteMacro : ICommand, ICommandPrototype
    {
        private string macroname;
        private bool executeSucceeded;
        private IResult lastResult;
        private StringBuilder sb = new StringBuilder();

        public IHelpDescription Description
        {
            get;
            private set;
        }


        private static void loadEmulator()
        {
            var zombie = new ExecuteMacro(new HelpDescription() { Name = "run macro", Description = "run the macro" });
            ICommandPrototypeRegistry r = AppResources.getInstance().getCommandRegistry();
            r.register("run-macro", zombie);
        }

        #region Constructor

        private ExecuteMacro(IHelpDescription description)
        {
            //for zombie
            this.Description = description;
        }


        private ExecuteMacro()
        {

        }
        private ExecuteMacro(string macroname)
        {
            this.macroname = macroname;
            executeSucceeded = false;
        }

        #endregion

        #region ICommand Members

        public IResult execute()
        {
            this.executeSucceeded = false;
            sb = new StringBuilder();
            IFSFileSystem fileSystem = AppResources.getInstance().getFileSystem();
            bool isMacroExist = fileSystem.MacroDefintion.ContainsKey(macroname);

            if (isMacroExist == false)
            {
                return new Result(true, "No match found");
            }

            IMacroDefintion macroDefintion = fileSystem.MacroDefintion[macroname];
            foreach (ICommand command in macroDefintion.CommandList)
            {
                lastResult = command.execute();
                sb.AppendLine(lastResult.getResult());
            }

            this.executeSucceeded = true;
            return new Result(sb.ToString());


        }

        public void undo()
        {
            IFSFileSystem fileSystem = AppResources.getInstance().getFileSystem();
            IMacroDefintion macroDefintion = fileSystem.MacroDefintion[macroname];
            foreach (ICommand command in macroDefintion.CommandList.Reverse())
            {
                command.undo();
            }
        }

        public IResult redo()
        {
            sb = new StringBuilder();
            IFSFileSystem fileSystem = AppResources.getInstance().getFileSystem();
            IMacroDefintion macroDefintion = fileSystem.MacroDefintion[macroname];
            foreach (ICommand command in macroDefintion.CommandList)
            {
                sb.AppendLine( command.redo().getResult());
            }

            return new Result(sb.ToString());
        }

        public string describe(IPrintContext context)
        {
            return context.getFormattedString("run-macro " + macroname + "(" + executeSucceeded + ").");
        }
        #endregion

        #region ICommandPrototype Members

        ICommand ICommandPrototype.clone()
        {
            return new ExecuteMacro();
        }

        ICommand ICommandPrototype.clone(string arg)
        {
            return new ExecuteMacro(arg);
        }

        #endregion
    }
}
